package blocksim.util;

import java.util.BitSet;
import java.util.Random;

public class ArrayUtils {

  public static BitSet byteArrayToBitSet(byte[] bytes) {
    int sizeInBits = bytes.length * 8;
    BitSet bits = new BitSet(sizeInBits);
    for (int i = 0; i < sizeInBits; i++) {
      if ((bytes[bytes.length - i / 8 - 1] & (1 << (i % 8))) > 0) {
        bits.set(i);
      }
    }
    return bits;
  }

  public static byte[] bitSetToByteArray(BitSet bits) {
    byte[] bytes = new byte[(int) Math.ceil(bits.size() / 8)];
    for (int i = 0; i < bits.length(); i++) {
      if (bits.get(i)) {
        bytes[bytes.length - i / 8 - 1] |= 1 << (i % 8);
      }
    }
    return bytes;
  }

  private static BitSet updateData(BitSet dataBs, int dataSize, double flipProb) {
    int flipped = 0;
    for (int i = nextGeometric(flipProb); i < dataSize; i += nextGeometric(flipProb) + 1) {
      dataBs.flip(i);
      flipped++;
    }
    return dataBs;
  }

  public static void generateRandomData(byte[] buffer) {
    Random rand = new Random();
    rand.nextBytes(buffer);
  }

  public static int nextGeometric(double p, double u) {
    int res = (int) Math.floor(Math.log(u) / Math.log(1.0 - p));
    return res;
  }

  public static int nextGeometric(double p) {
    return nextGeometric(p, Math.random());
  }
}
